#include "iot/thing.h"
#include "board.h"
#include "iot_servo.h"
#include "audio_codec.h"

#include <driver/gpio.h>
#include <driver/ledc.h>

#include <esp_log.h>

#define TAG "Serve"

namespace iot {

class Serve : public Thing {
private:      
    bool door_ = false;

    void InitializeServo() {
        // Prepare and then apply the LEDC PWM timer configuration
        ledc_timer_config_t serve_timer = {
            .speed_mode       = LEDC_LOW_SPEED_MODE,
            .duty_resolution  = LEDC_TIMER_13_BIT,
            .timer_num        = LEDC_TIMER_1,
            .freq_hz          = 50,
            .clk_cfg          = LEDC_AUTO_CLK
        };
        ledc_timer_config(&serve_timer);

        // Prepare and then apply the LEDC PWM channel configuration
        ledc_channel_config_t sevre_channel = {
            .gpio_num       = 20,
            .speed_mode     = LEDC_LOW_SPEED_MODE,
            .channel        = LEDC_CHANNEL_7,
            .intr_type      = LEDC_INTR_DISABLE,
            .timer_sel      = LEDC_TIMER_1,
            .duty   = 0,
            .hpoint = 0
        };
        ledc_channel_config(&sevre_channel);
    }

    void ServeSetDuty(uint32_t duty) {
        ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_7, duty);
        ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_7);
    }
    void ServeSetAngle(float angle) {
        uint16_t pulse_width_us=0;
        uint32_t duty;
        if(angle>180){angle=180;}
        else if(angle<0){angle=0;}
        pulse_width_us=(500 +(2500-500)*(angle /180));
        duty=pulse_width_us * 50 *((1<<13)-1) / 1e6;
        ServeSetDuty(duty);
    }

public:
    Serve() : Thing("Serve", "一个舵机"), door_(false) {
        InitializeServo();

        // 定义设备的属性
        properties_.AddBooleanProperty("door", "舵机是否转动", [this]() -> bool {
            return door_;
        });

        // 定义设备可以被远程执行的指令

     

        methods_.AddMethod("Serve_On", "转到180度", ParameterList(), [this](const ParameterList& parameters) {
            door_ = true;
            ServeSetAngle(180);
        });
        methods_.AddMethod("Serve_Half_On", "转到90度", ParameterList(), [this](const ParameterList& parameters) {
            door_ = true;
            ServeSetAngle(90);
        });
        methods_.AddMethod("Serve_Off", "回到0度", ParameterList(), [this](const ParameterList& parameters) {
            door_ = false;
            ServeSetAngle(0);
        });

        methods_.AddMethod("Serve_dd", "设置舵机角度", ParameterList({
            Parameter("brightness", "0到180之间的整数", kValueTypeNumber, true)
        }), [this](const ParameterList& parameters) {
            uint8_t brightness = static_cast<uint8_t>(parameters["brightness"].number());
            door_ = true;
            ServeSetAngle(brightness);
        });


    }
};

} // namespace iot

DECLARE_THING(Serve);
